<template>
	<div class="chart-box" ref="chartEl"></div>
</template>

<script lang="ts" setup>
import { onBeforeUnmount, onMounted, shallowRef, watch, watchEffect } from "vue-demi";
import * as echarts from "echarts/core";
import { toRefs, useResizeObserver } from "@vueuse/core";
import { ECOption } from "@/plugins/echarts";

interface Props {
	option: ECOption;
	// 图表在组件根元素尺寸变化时是否需要自动进行重绘。
	autoresize?: boolean;
	// 主题
	theme?: string | Record<string, unknown>;
	// 图表更新的配置项
	updateOptions?: echarts.SetOptionOpts;
	// 是否手动执行setOption
	manual?: boolean;
	// loading
	loading?: boolean;
	// loading配置
	loadingOptions?: Record<string, any>;
	// style
	width?: string;
	height?: string;
}
const props = withDefaults(defineProps<Props>(), {
	autoresize: true,
	loading: false,
	loadingOptions: () => ({ text: "图表正在加载，请稍等~" }),
	width: "100%",
	height: "100%"
});

const { autoresize, loading } = toRefs(props);

const chart = shallowRef<echarts.ECharts>();
const chartEl = shallowRef<HTMLElement | null>();

const setOption = (option: ECOption, updateOptions?: echarts.SetOptionOpts) => {
	chart.value && chart.value.setOption(option, updateOptions);
};

const mount = () => {
	chart.value = echarts.init(chartEl.value!, props.theme);
	props.manual || watchEffect(() => setOption(props.option, props.updateOptions));
};

// 自动监听元素变化改变图形
autoresize.value &&
	useResizeObserver(chartEl, (entries) => {
		const entry = entries[0];
		const { width, height } = entry.contentRect;
		if (width && height && chart.value) {
			chart.value.resize();
		}
	});

onMounted(() => {
	mount();
	watch(
		loading,
		(val) => {
			const $chart = chart.value;
			if ($chart) {
				val ? $chart.showLoading(props.loadingOptions) : $chart.hideLoading();
			}
		},
		{ immediate: true }
	);
});

onBeforeUnmount(() => {
	chart.value && chart.value.dispose();
});

defineExpose({ setOption, chart });
</script>

<style scoped>
.chart-box {
	width: v-bind(width);
	height: v-bind(height);
}
</style>
